# -*- coding: utf8 -*-
import os

from google.appengine.ext import ndb

import jinja2
import webapp2
import json

from google.appengine.api import memcache
from google.appengine.api import taskqueue
from google.appengine.api.logservice import logservice

from game_template import *
from game_history import *

import edit_game_forms
import edit_user_forms
import create_game_results
import show_word_statistic
import recalc_statistic
import constants

JINJA_ENVIRONMENT = jinja2.Environment(
    loader=jinja2.FileSystemLoader(os.path.dirname(__file__)),
    extensions=['jinja2.ext.autoescape'])


def json_to_game_history(json_history):
    json_unparsed = json.loads(json_history)
    game_log = json_unparsed['rounds']
    result = GameHistory()
    result.json_string = json_history
    players = set()
    for round_ in game_log:
        if not(round_['player1'] is None):
            players.add(round_['player1'])
        if not(round_['player2'] is None):
            players.add(round_['player2'])
        for words_ in round_['words']:
            if not(words_['owner'] is None):
                players.add(words_['owner'])
    if "words_in_hat" in json_unparsed:
        for word in json_unparsed["words_in_hat"]:
            if not(word['owner'] is None):
                players.add(word['owner'])

    result.players = list(players)

    rounds = []
    for round_ in game_log:
        current_round = Round()
        current_round.player_explain =\
            result.players.index(round_['player1'])
        current_round.player_guess =\
            result.players.index(round_['player2'])
        if 'time' in round_:
            current_round.duration_time = round_['time']
        else:
            current_round.duration_time = -1
        rounds.append(current_round)
    result.rounds = rounds

    words = set()
    for round_ in game_log:
        for word_ in round_['words']:
            current_word = Word()
            current_word.text = word_['text']
            if word_['owner'] is not None:
                current_word.owner = result.players.index(word_['owner'])
            words.add(current_word)
    result.words = list(words)

    round_counter = 0
    guess_results = []
    for round_ in game_log:
        for word_ in round_['words']:
            current_result = WordGuessResult()
            current_result_word = Word()
            current_result_word.text = word_['text']
            if word_['owner'] is not None:
                current_result_word.owner =\
                    result.players.index(word_['owner'])
            current_result.word = result.words.index(current_result_word)
            current_result.result = WordGuessResult.int_repr[
                word_['result']]
            current_result.time_sec = word_['time']
            current_result.round_ = round_counter
            guess_results.append(current_result)
        round_counter += 1
    result.guess_results = guess_results

    if "words_in_hat" in json_unparsed:
        unused_words = []
        for word in json_unparsed["words_in_hat"]:
            current_word = Word()
            current_word.text = word['text']
            if not(word['owner'] is None):
                current_word.owner = result.players.index(word['owner'])
            if not(current_word in result.words):
                unused_words.append(current_word)
        result.unused_words = unused_words
    else:
        result.unused_words = []

    id_ = GameId()
    if not("remote_id" in json_unparsed) or json_unparsed["remote_id"] is None:
        id_.game_local = True
        id_.id_ = hash(json_history)
        # print('here')
    else:
        id_.game_local = False
        id_.id_ = json_unparsed["remote_id"]
        # print('there')
    result.id_ = id_

    if "pin" in json_unparsed:
        result.pin = int(json_unparsed["pin"])

    if "is_paired_strategy" in json_unparsed:
        result.is_paired = json_unparsed["is_paired_strategy"]
    else:
        result.is_paired = True

    json_game_type = json_unparsed.get('game_type', None)
    # TODO: delete this hack with checking 'None'
    if json_game_type is not None and json_game_type != 'None':
        print json_unparsed
        result.game_type =\
            GameHistory.int_repr_type.get(json_game_type,
                                          GameHistory.HAT_STANDART)
    else:
        result.game_type = GameHistory.HAT_STANDART
    return result


class CreateGameHistory(webapp2.RequestHandler):
    def post(self):
        json_history = self.request.get("history")
        result = json_to_game_history(json_history)
        send_to_stat = True
        put_to_db = True

        max_game_number = -1
        for game in GameHistory.get_by_ids(result.id_.id_):
            if game.game_number > max_game_number:
                max_game_number = game.game_number
        result.game_number = max_game_number + 1
        if result.game_number is None:
            result.game_number = 1
        if put_to_db:
            result.put()

        if send_to_stat:
            taskqueue.add(url='/add_word_statistic_from_game',
                          queue_name=constants.WORD_STATISTIC_QUEUE,
                          params={'key': result.key.urlsafe()})

        self.response.write("<ok></ok>")


class TestCreateGameHistory(webapp2.RequestHandler):
    def get(self):
        template = JINJA_ENVIRONMENT.get_template('create_game_history.html')
        self.response.write(template.render())


class CreateEmptyGame(webapp2.RequestHandler):
    def get(self):
        game = GameTemplate(id_=GameTemplate.get_new_id(), settings=
                            Settings(word_count=int(self.request.get(
                                'words_number'))), is_joinable=True)
        game.put()
        self.response.write(game.make_id_pin_json())


class MainMenu(webapp2.RequestHandler):
    def get(self):
        template = JINJA_ENVIRONMENT.get_template('main_menu.html')
        self.response.write(template.render())


class AddWordStatisticFromGame(webapp2.RequestHandler):
    def post(self):
        game = ndb.Key(urlsafe=self.request.get("key")).get()
        game.add_to_statistic()


class AddPlayerFromJson(webapp2.RequestHandler):
    def post(self):
        json_string = self.request.get('json')
        all_json = json.loads(json_string)
        game = GameTemplate.get_by_id(int(all_json[u'id']),
                                      int(all_json[u'pin']))
        if all_json[u'name'] in game.players:
            self.error(409)
            return
        game.players.append(all_json[u'name'])
        for word in all_json[u'words']:
            game.words.append(word)
            game.owners.append(len(game.players)-1)
        game.put()


class GetJoinedPlayers(webapp2.RequestHandler):
    def get(self):
        try:
            game = GameTemplate.get_by_id(int(self.request.get('game_id')),
                                          int(self.request.get('pin')))
        except WrongPincodeError:
            self.error(403)
            return
        if game is None:
            self.error(404)
            return
        self.response.write(game.make_added_players_json())
        game.put()


application = webapp2.WSGIApplication([
    ("/create_game.html", edit_game_forms.CreateGameForm),
    ("/", MainMenu),
    ("/main_menu.html", MainMenu),
    ("/edit_game.html", edit_game_forms.EditGameForm),
    ("/process_creating_game", edit_game_forms.ProcessCreatingGame),
    ("/process_editing_game", edit_game_forms.ProcessEditingGame),
    ("/game_template_json", edit_game_forms.GetGameTemplateJson),
    ("/add_player_to_game.html", edit_game_forms.AddPlayerToGameForm),
    ("/process_adding_player", edit_game_forms.ProcessAddingPlayer),
    ("/choose_game.html", edit_game_forms.ChooseGameForm),
    ("/delete_statistics", edit_game_forms.DeleteStatistics),
    ("/show_game_results.html", edit_game_forms.ShowGameResults),
    ("/user_cabinet.html", edit_user_forms.ProcessAuth),
    ("/create_game_history", CreateGameHistory),
    ("/create_game_history.html", TestCreateGameHistory),
    ("/add_word_statistic_from_game", AddWordStatisticFromGame),
    ("/word_statistic.html", show_word_statistic.ShowWordStatistic),
    ("/game_results", create_game_results.CreateGameResults),
    ("/many_game_results", create_game_results.CreateManyGamesResults),
    ("/process_generating_pin", edit_user_forms.ProcessGeneratingPin),
    ("/process_editing_player", edit_user_forms.ProcessEditingPlayer),
    ("/create_empty_game", CreateEmptyGame),
    ("/recalc_all_statistics", recalc_statistic.RecalcAllStatistic),
    ("/recalc_all_stat_from_queue",
        recalc_statistic.RecalcAllStatisticFromQueue),
    ("/add_all_stat", recalc_statistic.AddAllStatistic),
    ("/delete_word_statistic", recalc_statistic.DeleteWordStatistic),
    ("/add_player_from_json", AddPlayerFromJson),
    ("/edit_user.html", edit_user_forms.EditUser),
    ("/get_joined_players", GetJoinedPlayers)
], debug=True)
